package token

import (
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"time"
)

type TokenContext struct {
	Id       uint64
	UserName string
}

func Sign(c TokenContext, secret string) (tokenString string, err error) {
	if secret == "" {
		secret = viper.GetString("jwt_key")
	}
	// 生成token内容
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"id":       c.Id,
		"username": c.UserName,
		"exp":      int(time.Now().Unix()) + viper.GetInt("expir"), // 过期时间
	})
	// 生成token
	tokenString, err = token.SignedString([]byte(secret))
	return
}

func ValidateToken(c *gin.Context) (*TokenContext, error) {
	// 服务器就获取http头部字段
	tokenstring := c.Request.Header.Get("Token")
	ctx := &TokenContext{}
	if tokenstring == "" {
		return ctx, fmt.Errorf("token为空")
	}
	// 解析token
	token, err := jwt.Parse(tokenstring, secretFunc)
	if err != nil {
		return ctx, err
	} else if claims, ok := token.Claims.(jwt.MapClaims); ok {
		ctx.Id = uint64(claims["id"].(float64))
		ctx.UserName = claims["username"].(string)
		return ctx, nil
	} else {
		return ctx, fmt.Errorf("无法解析！")
	}
}

func secretFunc(token *jwt.Token) (interface{}, error) {
	return []byte(viper.GetString("jwt_key")), nil
}
